package api

import (
	"bufio"
	"encoding/json"
	"log"
	"os"
)

type GenericBffService struct {
	serviceDefine *BffServiceDefine
}

func NewGenericBffService(path string) *GenericBffService {
	if path == "" {
		log.Fatal("path is invalid")
		return nil
	}
	serviceDefine, error := _parseBffServiceDefineJson(path)
	if error != nil {
		log.Fatal(error)
		return nil
	}
	return &GenericBffService{
		serviceDefine: serviceDefine,
	}
}

func (_this *GenericBffService) FragmentData(clientType string, originData map[string]interface{}) map[string]interface{} {
	if clientType == "" {
		clientType = "mobile"
	}
	if originData == nil {
		log.Fatal("originData is nil")
		return nil
	}
	propsData := _getFragmentData(clientType, _this.serviceDefine.Props)
	return _mergeData(propsData, originData)
}

func _getFragmentData(clientType string, f *Props) []string {
	if clientType == "pc" {
		return f.PC
	} else if clientType == "mobile" {
		return f.Mobile
	} else if clientType == "richscreen" {
		return f.RichScreen
	}
	return nil
}
func _mergeData(props []string, srcData map[string]interface{}) map[string]interface{} {
	retData := map[string]interface{}{}
	if len(props) == 0 {
		retData = srcData
	} else {
		for key, value := range srcData {
			for _, prop := range props {
				if key != prop {
					retData[key] = value
				}
			}
		}
	}
	return retData
}

func (_this *GenericBffService) CombineAPIs(callback func(data []*ResponseValue)) {
	if callback == nil {
		log.Fatal("callback is nil")
		return
	}
	var requestAPIs []string
	for _, api := range *_this.serviceDefine.Combine {
		requestAPIs = append(requestAPIs, api.Remote+api.Path)
	}
	cmb := CreateCombineAPIs(len(requestAPIs))
	cmb.Barrier(requestAPIs...)
	cmb.ResponseData(func(data []*ResponseValue) {
		if data == nil {
			log.Fatal("data is nil")
			return
		}
		callback(data)
	})
}
func _parseBffServiceDefineJson(path string) (*BffServiceDefine, error) {
	var bffServiceDefine *BffServiceDefine = &BffServiceDefine{}
	file, error := os.Open(path)
	if error != nil {
		panic(error)
	}
	defer file.Close()
	reader := bufio.NewReader(file)
	decoder := json.NewDecoder(reader)
	if error = decoder.Decode(bffServiceDefine); error != nil {
		return nil, error
	}
	return bffServiceDefine, nil
}
